<template>
  <div class="p-2">
    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
      <div v-show="showSearch" class="mb-[10px]">
        <el-card shadow="hover">
          <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="68px">
            <el-form-item label="栏目名称" prop="title">
              <el-input 
                v-model="queryParams.title" 
                placeholder="请输入栏目名称" 
                clearable 
                @keyup.enter="handleQuery"
                :prefix-icon="Search"
              />
            </el-form-item>
            <el-form-item label="栏目类型" prop="categoryType">
              <el-select v-model="queryParams.categoryType" placeholder="栏目类型" clearable class="w-[180px]">
                <el-option v-for="dict in categoryTypeOptions" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
              <el-button icon="Refresh" @click="resetQuery">重置</el-button>
            </el-form-item>
          </el-form>
        </el-card>
      </div>
    </transition>

    <el-card shadow="never">
      <template #header>
        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['cms:articleCategory:add']">新增栏目</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['cms:articleCategory:edit']"
              >修改</el-button
            >
          </el-col>
          <el-col :span="1.5">
            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['cms:articleCategory:remove']"
              >删除</el-button
            >
          </el-col>
          <el-col :span="1.5">
            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['cms:articleCategory:export']">导出</el-button>
          </el-col>
          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
        </el-row>
      </template>

      <el-table v-loading="loading" :data="articleCategoryList" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column prop="title" label="栏目名称" min-width="260" show-overflow-tooltip>
          <template #default="scope">
            <span 
              :class="[
                'category-title', 
                { 'is-parent': scope.row.parentId === '0' }
              ]"
            >
              {{ scope.row.title }}
            </span>
          </template>
        </el-table-column>
        <el-table-column label="上级栏目" prop="parentId" width="180">
          <template #default="scope">
            <span v-if="scope.row.parentId == '0'" class="text-primary">顶级栏目</span>
            <span v-else-if="scope.row.parentId === undefined" class="text-muted">无</span>
            <span v-else class="text-primary">{{ getParentName(scope.row.parentId) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="URL别名" align="center" prop="slug" width="180" />
        <el-table-column label="排序" align="center" prop="sort" width="80" />
        <el-table-column label="显示状态" align="center" prop="isShow" width="100">
          <template #default="scope">
            <dict-tag :options="cms_is_show" :value="scope.row.isShow" />
          </template>
        </el-table-column>
        <el-table-column label="状态" align="center" prop="status" width="100">
          <template #default="scope">
            <dict-tag :options="sys_normal_disable" :value="scope.row.status" />
          </template>
        </el-table-column>
        <el-table-column label="创建时间" align="center" prop="createTime" width="180">
          <template #default="scope">
            <span>{{ parseTime(scope.row.createTime) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="导航菜单" align="center" show-overflow-tooltip min-width="200">
          <template #default="{ row }">
            <template v-if="row.menuIds?.length">
              <el-tag 
                v-for="menuId in row.menuIds" 
                :key="menuId"
                size="small"
                class="mr-1"
              >
                {{ getMenuName(menuId) }}
              </el-tag>
            </template>
            <span v-else class="text-gray-400">无</span>
          </template>
        </el-table-column>
        <el-table-column label="栏目类型" prop="categoryType" width="100" align="center">
          <template #default="{ row }">
            <el-tag :type="getTagType(row.categoryType)">
              {{ getCategoryTypeLabel(row.categoryType) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="250" class-name="small-padding fixed-width">
          <template #default="scope">
            <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['cms:articleCategory:add']">新增</el-button>
            <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['cms:articleCategory:edit']">修改</el-button>
            <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['cms:articleCategory:remove']">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
    </el-card>
    <!-- 添加或修改CMS文章分类对话框 -->
    <el-dialog :title="dialog.title" v-model="dialog.visible" width="700px" append-to-body>
      <el-form ref="articleCategoryFormRef" :model="form.value" :rules="rules" label-width="100px">
        <el-form-item label="上级栏目" prop="parentId">
          <el-tree-select
            v-model="form.value.parentId"
            :data="categoryOptions"
            :props="{ label: 'title', value: 'id', children: 'children' }"
            value-key="id"
            placeholder="选择上级栏目"
            check-strictly
            class="w-full"
          />
        </el-form-item>
        <el-form-item label="栏目名称" prop="title">
          <el-input v-model="form.value.title" placeholder="请输入栏目名称" />
        </el-form-item>
        <el-form-item label="URL别名" prop="slug">
          <el-input v-model="form.value.slug" placeholder="请输入URL别名">
            <template #append>.html</template>
          </el-input>
        </el-form-item>
        <el-form-item label="分类描述" prop="description">
          <el-input v-model="form.value.description" placeholder="请输入分类描述" />
        </el-form-item>
        <el-form-item label="关键词" prop="keywords">
          <el-input v-model="form.value.keywords" placeholder="请输入关键词" />
        </el-form-item>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="显示状态" prop="isShow">
              <el-radio-group v-model="form.value.isShow">
                <el-radio v-for="dict in cms_is_show" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="分类状态" prop="status">
              <el-radio-group v-model="form.value.status">
                <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="显示顺序" prop="sort">
              <el-input-number v-model="form.value.sort" :min="0" :max="999" controls-position="right" class="w-[100%]" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="模板" prop="template">
              <el-select v-model="form.value.template" placeholder="请选择模板" clearable class="w-[100%]">
                <el-option label="默认模板" value="default" />
                <el-option label="图文模板" value="image" />
                <el-option label="列表模板" value="list" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="form.value.remark" placeholder="请输入备注" />
        </el-form-item>
        <el-col :span="24">
          <el-form-item label="导航菜单" prop="menuIds">
            <el-tree-select
              v-model="form.menuIds"
              :data="menuOptions"
              :props="{ 
                label: 'title', 
                value: 'id', 
                children: 'children' 
              }"
              multiple
              show-checkbox
              check-strictly
              value-key="id"
              placeholder="请选择导航菜单"
              class="w-full"
            >
              <template #default="{ node, data }">
                <span>{{ data.title }}</span>
                <span v-if="data.categoryType" class="text-gray-400 ml-2">
                  ({{ getCategoryTypeLabel(data.categoryType) }})
                </span>
              </template>
            </el-tree-select>
            <div class="form-tips">可以选择多个菜单项，用于前台导航显示</div>
          </el-form-item>
        </el-col>
        <el-form-item label="栏目类型" prop="categoryType">
          <el-select v-model="form.value.categoryType" placeholder="请选择栏目类型" class="w-full">
            <el-option
              v-for="item in categoryTypeOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup name="ArticleCategory" lang="ts">
import { listArticleCategory, getArticleCategory, delArticleCategory, addArticleCategory, updateArticleCategory } from '@/api/cms/articleCategory';
import { ArticleCategoryVO, ArticleCategoryQuery, ArticleCategoryForm } from '@/api/cms/articleCategory/types';

const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { sys_normal_disable, cms_is_show } = toRefs<any>(proxy?.useDict('sys_normal_disable', 'cms_is_show'));
const articleCategoryList = ref<ArticleCategoryVO[]>([]);
const buttonLoading = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);

const queryFormRef = ref<ElFormInstance>();
const articleCategoryFormRef = ref<ElFormInstance>();

const dialog = reactive<DialogOption>({
  visible: false,
  title: ''
});

const categoryTypeOptions = ref([
  { label: '文章栏目', value: CategoryType.ARTICLE },
  { label: '单页栏目', value: CategoryType.PAGE },
  { label: '链接栏目', value: CategoryType.LINK }
]);

const initFormData: ArticleCategoryForm = {
  id: undefined,
  parentId: 0,
  title: undefined,
  slug: undefined,
  description: undefined,
  keywords: undefined,
  sort: 0,
  template: 'default',
  isShow: '2',
  status: '0',
  categoryType: CategoryType.ARTICLE,
  remark: undefined,
  menuIds: []
};
const form = reactive({
  value: { ...initFormData }
});
const queryParams = ref({
  pageNum: 1,
  pageSize: 10,
  parentId: undefined,
  title: undefined,
  slug: undefined,
  description: undefined,
  keywords: undefined,
  sort: undefined,
  template: undefined,
  isShow: undefined,
  status: undefined,
  params: {}
});
const rules = {
  parentId: [{ required: true, message: '父分类ID不能为空', trigger: 'blur' }],
  title: [{ required: true, message: '分类名称不能为空', trigger: 'blur' }],
  slug: [{ required: true, message: 'URL别名不能为空', trigger: 'blur' }],
  description: [{ required: true, message: '分类描述不能为空', trigger: 'blur' }],
  keywords: [{ required: true, message: '关键词不能为空', trigger: 'blur' }],
  sort: [{ required: true, message: '显示顺序不能为空', trigger: 'blur' }],
  template: [{ required: true, message: '模板不能为空', trigger: 'blur' }],
  isShow: [{ required: true, message: '显示状态不能为空', trigger: 'change' }],
  status: [{ required: true, message: '分类状态不能为空', trigger: 'change' }]
};

/** 查询CMS文章分类列表 */
const getList = async () => {
  loading.value = true;
  try {
    const res = await listArticleCategory(queryParams.value);
    articleCategoryList.value = res.rows.map((item) => {
      if (item.parentId && item.parentId !== 0) {
        const parent = res.rows.find((p) => p.id === item.parentId);
        if (parent) {
          item.parentName = parent.title;
        }
      } else {
        item.parentName = '无上级分类';
      }
      return item;
    });
    total.value = res.total;
  } finally {
    loading.value = false;
  }
};

/** 取消按钮 */
const cancel = () => {
  reset();
  dialog.visible = false;
};

/** 表单重置 */
const reset = () => {
  Object.assign(form.value, initFormData);
  articleCategoryFormRef.value?.resetFields();
};

/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.value.pageNum = 1;
  getList();
};

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value?.resetFields();
  handleQuery();
};

/** 多选框选中数据 */
const handleSelectionChange = (selection: ArticleCategoryVO[]) => {
  ids.value = selection.map((item) => item.id);
  single.value = selection.length != 1;
  multiple.value = !selection.length;
};

/** 分类选项 */
const categoryOptions = ref<ArticleCategoryVO[]>([]);

/** 获取分类选项数据 */
const getCategoryOptions = async () => {
  try {
    const res = await listArticleCategory({
      status: '0',
      pageSize: 999
    });

    const processedRows = res.rows.map((item) => ({
      ...item,
      parentName: (() => {
        if (item.parentId && item.parentId !== 0) {
          const parent = res.rows.find((p) => p.id === item.parentId);
          return parent ? parent.title : '';
        }
        return '';
      })()
    }));

    categoryOptions.value = processedRows.filter((item) => {
      if (form.value?.id) {
        return item.id !== form.value.id && !isChildCategory(item, form.value.id);
      }
      return true;
    });
  } catch (error) {
    console.error('获取分类选项失败:', error);
    categoryOptions.value = [];
  }
};

/** 判断是否为指定分类的子分类 */
const isChildCategory = (category: ArticleCategoryVO, parentId: number): boolean => {
  if (!category || !parentId) {
    return false;
  }

  if (!category.parentId) {
    return false;
  }

  if (category.parentId === parentId) {
    return true;
  }

  const parent = articleCategoryList.value.find((item) => item.id === category.parentId);
  return parent ? isChildCategory(parent, parentId) : false;
};

/** 新增按钮操作 */
const handleAdd = async (row?: ArticleCategoryVO) => {
  reset();
  await getCategoryOptions();
  if (row?.id) {
    form.value.parentId = row.id;
  } else {
    form.value.parentId = 0;
  }
  dialog.visible = true;
  dialog.title = '添加分类';
};

/** 修改按钮操作 */
const handleUpdate = async (row?: ArticleCategoryVO) => {
  reset();
  await getCategoryOptions();
  const id = row?.id || ids.value[0];
  try {
    const res = await getArticleCategory(id);
    form.value = { ...res.data };
    dialog.visible = true;
    dialog.title = '修改分类';
  } catch (error) {
    console.error('获取分类详情失败:', error);
  }
};

/** 提交按钮 */
const submitForm = () => {
  articleCategoryFormRef.value?.validate(async (valid: boolean) => {
    if (valid) {
      buttonLoading.value = true;
      try {
        if (form.value.id) {
          await updateArticleCategory(form.value);
        } else {
          await addArticleCategory(form.value);
        }
        proxy?.$modal.msgSuccess('操作成功');
        dialog.visible = false;
        await getList();
      } finally {
        buttonLoading.value = false;
      }
      reset();
    }
  });
};

/** 删除按钮操作 */
const handleDelete = async (row?: ArticleCategoryVO) => {
  const _ids = row?.id || ids.value;
  await proxy?.$modal.confirm('是否确认删除CMS文章分类编号为"' + _ids + '"的数据项？').finally(() => (loading.value = false));
  await delArticleCategory(_ids);
  proxy?.$modal.msgSuccess('删除成功');
  await getList();
};

/** 导出按钮操作 */
const handleExport = () => {
  proxy?.download(
    'cms/articleCategory/export',
    {
      ...queryParams.value
    },
    `articleCategory_${new Date().getTime()}.xlsx`
  );
};

// 导航菜单选项
const menuOptions = ref<ArticleCategoryVO[]>([]);

// 获取导航菜单选项
const getMenuOptions = async () => {
  try {
    const res = await listArticleCategory({
      status: '0'
    });
    const list = res.rows || [];
    // 构建树形数据
    const treeData = handleTree(list, 'id', 'parentId');
    // 过滤掉当前编辑的分类及其子分类
    menuOptions.value = form.value.id ? 
      filterCurrentCategory(treeData, form.value.id) : 
      treeData;
  } catch (error) {
    console.error('获取导航菜单选项失败:', error);
  }
};

// 过滤当前分类及其子分类
const filterCurrentCategory = (list: ArticleCategoryVO[], currentId: string): ArticleCategoryVO[] => {
  return list.filter(item => {
    if (item.id === currentId) {
      return false;
    }
    if (item.children && item.children.length) {
      item.children = filterCurrentCategory(item.children, currentId);
    }
    return true;
  });
};

// 添加获取菜单名称的方法
const getMenuName = (menuId: string) => {
  const findMenu = (list: ArticleCategoryVO[], id: string): string => {
    for (const item of list) {
      if (item.id === id) {
        return item.title;
      }
      if (item.children) {
        const name = findMenu(item.children, id);
        if (name) return name;
      }
    }
    return '';
  };
  return findMenu(articleCategoryList.value, menuId) || menuId;
};

// 添加获取栏目类型标签的方法
const getCategoryTypeLabel = (type: string) => {
  const option = categoryTypeOptions.value.find(item => item.value === type);
  return option ? option.label : '未知类型';
};

onMounted(() => {
  getList();
  getCategoryOptions();
});
</script>

<style lang="scss" scoped>
.category-icon {
  margin-right: 8px;
  font-size: 16px;
  vertical-align: middle;
}
</style>
